#! /usr/bin/env python

# NM64_BIN KIEL
#
# Copyright (C) 2010-2011 Christian T. Steigies <steigies@physik.uni-kiel.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""KIEL data format
Copyright (c) 2010-2011 Christian T. Steigies <steigies@physik.uni-kiel.de>

This module offers functions to read NM64 BIN data as used in KIEL
and return data in the format as used by NMDB."""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

import os
import sys
import datetime

#import MySQLdb # python-mysqldb

#http://docs.python.org/library/sqlite3.html
# SpaceWx uses CentOS5 with Python2.4 and pysqlite2
try:
    from pysqlite2 import dbapi2 as sqlite3
except ImportError:
    try:
        from sqlite3 import dbapi2 as sqlite3
    except ImportError:
        print "SQLite module not found"
        sys.exit(1)

#from tools.datetool import str2datetime

from nm64_class import nm64, row2insert

## --------------------------------------------------------------------------
def ReadBIN(filename):
    # read BIN file into chunk
    
    if os.path.exists(filename):
        binsize = os.stat(filename).st_size
        if (binsize) == 3120:
            print "opening %s" % (filename)
            BIN = open(filename, "rb")
            chunk = BIN.read(60*26*2) # 60 Minuten a 26 Worte a 2 byte
            BIN.close()
        else:
            print "file %s is corrupt, size is %i bytes instead of 3120 bytes" %(filename, binsize)
            sys.exit(1)
    else:
        print "file not found: %s" % (filename)
        sys.exit(1)

    return(chunk)


def BIN2frame(chunk):
    # convert BIN data to frame

    # create a 60*26 array filled with zero
    frame = []
    for i in range (0,60):
        frame.append([0]*26)

    for i in range(0,60):
        for j in range(0,26):
            word = ord(chunk[26*2*i+2*j+0])+256*ord(chunk[26*2*i+2*j+1])
            frame[i][j] = word

    return(frame)


def frame2BIN(frame):
    # convert frame to BIN chunk

    chunk = ''
    for i in range(0,60):
        for j in range(0,26):
            word = frame[i][j]
            hb   = int(word / 256)
            lb   = (word - 256*hb)
            word2 = lb+256*hb
            #print "%5i %3i %3i %5i" %(word, lb, hb, word2)

            chunk += chr(lb)+chr(hb)

    return(chunk)


def PrintFrame(frame):
    # print out frame
    # determine if frame contains zeros -> shift_frame

    shift_frame = 0
    print "\nmin",
    for i in range(0,18):
        print "zr#%02i " %(i+1),
    print "press  temp0  temp1   HV1    HV2    HV3  deltaT   hour"

    for i in range(0,60):
        linesum = 0
        print "\n %02i" %(i), 
        for j in range(0,26):
            print "%5i " %(frame[i][j]),
            linesum = linesum + frame[i][j]
        #c=0.0549254*(256*256*frame[i][25]+frame[i][24])
        #print c,
        #print "%02i:" %(c div 3600) # time in seconds
        if (linesum == 0):
            ## empty line found -> all data needs to be shifted to the end of the frame
            ## check if hour in last line = current_hour+1 ?
            print "NO DATA",
            if not(shift_frame):
                shift_frame = i

    print "\n"

    return(shift_frame)

## --------------------------------------------------------------------------
class kiel(nm64):
    def __init__(self, station, year, month, day, hour):
        """read 1hour of BIN data for station kiel
        """

        nm64.__init__(self, station, year, month, day, hour)

        # get one hour of data
        file = "/data/kermes/NM64/%04i/bin/%02i%02i%02i%02i.bin" %(year, year%100, month, day, hour)
        chunk = ReadBIN(file)
        frame = BIN2frame(chunk)

        # store data in internal sqlite database
        for i in range(0,60):
            row = [self.dt(i)]
            for j in range(0,26): # 18 channels, pressure, temp1, temp2, hv1, hv2, hv3, dt, hour: 26 values
                row.append(frame[i][j])
            #print row
            querystring = row2insert(row)
            #print "Query", querystring
            self._c.execute(querystring)


    def _value(self, minute):
        """return values as read in"""
        
        dt = str(datetime.datetime(self._year, self._month, self._day, self._hour, minute, 0))
        cols = "ch01, ch02, ch03, ch04, ch05, ch06, ch07, ch08, ch09, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, pressure"
        querystring = "SELECT %s FROM data WHERE datetime == \"%s\"" %(cols, dt)
        self._c.execute(querystring)
        row = self._c.fetchone() # should return only one line, or None
        #print "SQL:", row
        if row:
            return row
        else:
            return None

## --------------------------------------------------------------------------

if __name__=="__main__":
    print "This is the NM64_BIN KIEL module for NMWB."

    station = "kiel"
    year = 2011
    month = 11
    day = 1
    hour = 0

    if 0:
        file = "/data/kermes/NM64/%04i/bin/%02i%02i%02i%02i.bin" %(year, year%100, month, day, hour)


        chunk = ReadBIN(file)
        frame = BIN2frame(chunk)
        PrintFrame(frame)

    else:
        data = kiel(station, year, month, day, hour)
